<!DOCTYPE html>
<!--
Copyright (c) 2019 Joel Martin
Copyright (c) 2012 Fogus, Jen Myers and Relevance Inc.
All rights reserved. The use and distribution terms for this software
are covered by the Eclipse Public License 1.0
(http://opensource.org/licenses/eclipse-1.0.php) which can be found in
the file COPYING the root of this distribution.  By using this
software in any fashion, you are agreeing to be bound by the terms of
this license.  You must not remove this notice, or any other, from
this software.
-->

<html>
<head>
  <meta charset="UTF-8" />
  <link rel="stylesheet" type="text/css" href="web/base.css" />
  <link rel="stylesheet" type="text/css" href="web/layout.css" />
  <link rel="stylesheet" type="text/css" href="web/skeleton.css" />
  <link rel="stylesheet" type="text/css" href="web/himera.css" />
  <link rel="stylesheet" type="text/css" href="web/ansi.css" />
  <link rel="stylesheet" type="text/css" href="web/console.css" />
  <style type="text/css" media="screen">
  </style>
  <title>Mal Web REPL</title>
</head>
<body>
  <div class="container">
    <h1 id="title"><a href="https://github.com/kanaka/mal"/>Mal</a></h1>
    
    <h2>Mal Web REPL</h2>

    <!--
    <div id="editor-container" class="sixteen columns">
    <div id="tiny-note" class="tiny-note"></div>
    <textarea class="editor" id="editor">;; Develop your Mal program here.
;; Ctrl+E/Cmd+E evaluates file in the REPL.</textarea>
    </div>
    -->
    
    <div id="console-container" class="sixteen columns">
    <div class="console" id="console"></div>
    </div>
    <div class="eight columns">
    <!--
    <h3><span style="cursor: pointer" class="doc-link" id="toggle-editor">Show file editor</span></h3>
    -->
    <h3><span style="cursor: pointer" class="doc-link">&nbsp;</span></h3>
    </div>
    <div class="eight columns">
    <div class="source">
      <a href="http://github.com/kanaka/mal">View source on Github <img src="web/github-icon.png" /></a></p>
    </div><!-- /source -->
    </div>
    
    <div class="rule sixteen columns"></div>

	  <div class="sixteen columns">
    <h3>Mal at a glance</h3>
    </div>
    
    <div class="cheat-box-container eight columns">
      <div class="cheat-box">
        <h4>Datatypes</h4>
        <table>
          <tr class="row-one">
            <td class="row-label">Maps</td>
            <td>{"key1" "val1", "key2" 123}</td>
          </tr>
          <tr>
            <td class="row-label">Lists</td>
            <td>(1 2 3 "four")</td>
          </tr>
          <tr class="row-one">
            <td class="row-label">Vectors</td>
            <td>[1 2 3 4 "a" "b" "c" 1 2]</td>
          </tr>
          <tr>
            <td class="row-label">Scalars</td>
            <td>a-symbol, "a string", :a_keyword, 123, nil, true, false</td>
          </tr>
        </table>
      </div><!-- /cheat-box -->
      <div class="cheat-box">
        <h4>Functions</h4>
        <table>
          <tr class="row-one">
            <td class="row-label">Calling</td>
            <td>(<span class="ebnf">&lt;function&gt;</span>
	         <span class="ebnf">&lt;args*&gt;</span>)</td>
          </tr>
          <tr>
            <td class="row-label">Defining named functions</td>
            <td>(def! <span class="ebnf">&lt;name&gt;</span> 
                  (fn*
                  [<span class="ebnf">&lt;args*&gt;</span>]
                  <span class="ebnf">&lt;action&gt;</span>))</td>
          </tr>
          <tr class="row-one">
            <td class="row-label">Anonymous function</td>
            <td>(fn*
                  [<span class="ebnf">&lt;args*&gt;</span>]
                  <span class="ebnf">&lt;action&gt;</span>)</td>
          </tr>
        </table>
      </div><!-- /cheat-box -->
      <div class="cheat-box">
        <h4>Useful Macros and Special Forms</h4>
        <table>
          <tr class="row-one">
            <td class="row-label">Conditionals</td>
            <td>if cond or</td>
          </tr>
          <!--
          <tr>
            <td class="row-label">Nesting, chaining, and Interop</td>
            <td>-> ->> doto .. .</td>
          </tr>
          -->
          <tr>
            <td class="row-label">Multiple Actions (side-effects)</td>
            <td>(do 
                  <span class="ebnf">&lt;action*&gt;</span>...)</td>
          </tr>
          <tr class="row-one">
            <td class="row-label">Defining things</td>
            <td>def! defmacro! let*</td>
          </tr>
          <tr>
            <td class="row-label">Quoting</td>
            <td>' ` ~ ~@</td>
          </tr>
          <tr class="row-one">
            <td class="row-label">Examining macros</td>
            <td>macroexpand</td>
          </tr>
	</table>
      </div>
    </div><!-- /cheat-box-container -->

    <div class="cheat-box-container eight columns">
      <div class="cheat-box">
        <h4>Useful Functions</h4>
        <table>
          <tr class="row-one">
            <td class="row-label">Math</td>
            <td>+ - * /</td>
          </tr>
          <tr>
            <td class="row-label">Comparison/Boolean</td>
            <td>= < > <= >= not</td>
          </tr>
          <tr class="row-one">
            <td class="row-label">Predicates</td>
            <td>nil? true? false? symbol? keyword? string? list? vector? map? sequential?</td>
          </tr>
          <tr>
            <td class="row-label">Data processing</td>
            <td>map apply</td>
          </tr>
          <tr class="row-one">
            <td class="row-label">Data create</td>
            <td>list vector hash-map</td>
          </tr>
          <tr>
            <td class="row-label">Data inspection</td>
            <td>first rest get keys vals count get nth contains? empty?</td>
          </tr>
          <tr class="row-one">
            <td class="row-label">Data manipulation</td>
            <td>conj cons concat assoc dissoc</td>
          </tr>
          <tr>
            <td class="row-label">Lists and Vectors</td>
            <td>first rest nth seq</td></td>
          </tr>
          <tr class="row-one">
            <td class="row-label">Hash Maps</td>
            <td>get keys vals contains?</td></td>
          </tr>
          <tr>
            <td class="row-label">Strings</td>
            <td>str pr-str seq</td></td>
          </tr>
          <tr class="row-one">
            <td class="row-label">Atoms</td>
            <td>atom atom? deref[@] reset! swap!</td></td>
          </tr>
          <tr>
            <td class="row-label">Meta</td>
            <td>meta with-meta[^]</td></td>
          </tr>
          <tr class="row-one">
            <td class="row-label">Output</td>
            <td>println prn</td></td>
          </tr>
        </table>
      </div><!-- /cheat-box -->
      <div class="cheat-box">
        <h4>JavaScript Interop</h4>
        <table>
          <tr class="row-one">
            <td class="row-label">Evaluate JavaScript</td>
            <td>(js-eval "JS string to eval")</td>
          </tr>
          <tr>
            <td class="row-label">Method call/access</td>
            <td>(. js-fn arg...)</td>
          </tr>
	</table>
      </div>
    </div><!-- /cheat-box-container -->
        
    <div class="rule sixteen columns"></div>
    
    <div class="column footer-logo">
        <div>Mal &copy; 2019 Joel Martin</div>
        <div>Himera design &copy; 2012-2013 <a ref="http://www.fogus.me">Fogus</a>, <a href="http://jenmyers.net/">Jen Myers</a> and <a href="http://www.thinkrelevance.com">Relevance Inc.</a></div>
    </div>
    
  </div><!-- / container -->
  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script type="text/javascript" src="web/jqconsole.min.js"></script>
  <script type="text/javascript" src="web/mal.js"></script>
  <script>
    $(function() {
      // Creating the console.
      window.jqconsole = $('#console').jqconsole(null, 'user> ');

      printer.println = function () {
        var str = Array.prototype.join.call(arguments, " ")
        jqconsole.Write(str + "\n", 'jqconsole-output');
      }

      rep("(println (str \"Mal [\" *host-language* \"]\"))");

      jq_load_history(jqconsole);

      // Abort prompt on Ctrl+C.
      jqconsole.RegisterShortcut('C', function() {
        jqconsole.AbortPrompt();
        handler();
      });
      // Move to line start Ctrl+A.
      jqconsole.RegisterShortcut('A', function() {
        jqconsole.MoveToStart();
        handler();
      });
      // Move to line end Ctrl+E.
      jqconsole.RegisterShortcut('E', function() {
        jqconsole.MoveToEnd();
        handler();
      });
      jqconsole.RegisterMatching('{', '}', 'brace');
      jqconsole.RegisterMatching('(', ')', 'paren');
      jqconsole.RegisterMatching('[', ']', 'bracket');
      jqconsole.RegisterMatching('"', '"', 'dquote');
      // Handle a command.
      var handler = function(line) {
        if (line) {
          try {
            jqconsole.Write(rep(line) + '\n', 'jqconsole-return');
          } catch (exc) {
            if (exc instanceof reader.BlankException) { return; }
            if (exc.stack) {
              jqconsole.Write(exc.stack + '\n', 'jqconsole-error');
            } else {
              jqconsole.Write(exc + '\n', 'jqconsole-error');
            }
          }
          jq_save_history(jqconsole);
        }
        jqconsole.Prompt(true, handler);
        /*
        jqconsole.Prompt(true, handler, function(command) {
          // Continue line if can't compile the command.
          try {
            Function(command);
          } catch (e) {
            if (/[\[\{\(]$/.test(command)) {
              return 1;
            } else {
              return 0;
            }
          }
          return false;
        });
      */
      };

      // Initiate the first prompt.
      handler();
    });
  </script>

</body>
</html>
